﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.Framework.BasicFramework;
using IPC.Communication.Framework.Core;
using IPC.Communication.Framework.Core.IMessage;
using IPC.Communication.Framework.Core.Net;
using IPC.Communication.Framework.Reflection;

namespace IPC.Communication.Framework.Profinet.Beckhoff
{
    public class BeckhoffAdsNet : NetworkDeviceBase
    {
        private byte[] targetAMSNetId = new byte[8];

        private byte[] sourceAMSNetId = new byte[8];

        private string senderAMSNetId = string.Empty;

        private bool useTagCache = false;

        private readonly Dictionary<string, uint> tagCaches = new Dictionary<string, uint>();

        private readonly object tagLock = new object();

        private readonly SoftIncrementCount incrementCount = new SoftIncrementCount(2147483647L, 1L);

        [HslMqttApi(HttpMethod = "GET", Description = "Get or set the IP address of the remote server. If it is a local test, then it needs to be set to 127.0.0.1")]
        public override string IpAddress
        {
            get
            {
                return base.IpAddress;
            }
            set
            {
                base.IpAddress = value;
                string[] array = base.IpAddress.Split(new char[1]
			{
				'.'
			}, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < array.Length; i++)
                {
                    targetAMSNetId[i] = byte.Parse(array[i]);
                }
            }
        }

        public bool UseTagCache
        {
            get
            {
                return useTagCache;
            }
            set
            {
                useTagCache = value;
            }
        }

        public BeckhoffAdsNet()
        {
            base.WordLength = 2;
            targetAMSNetId[4] = 1;
            targetAMSNetId[5] = 1;
            targetAMSNetId[6] = 33;
            targetAMSNetId[7] = 3;
            sourceAMSNetId[4] = 1;
            sourceAMSNetId[5] = 1;
            base.ByteTransform = new RegularByteTransform();
        }

        public BeckhoffAdsNet(string ipAddress, int port)
            : this()
        {
            IpAddress = ipAddress;
            Port = port;
        }

        protected override INetMessage GetNewNetMessage()
        {
            return new AdsNetMessage();
        }

        public void SetTargetAMSNetId(string amsNetId)
        {
            if (!string.IsNullOrEmpty(amsNetId))
            {
                StrToAMSNetId(amsNetId).CopyTo(targetAMSNetId, 0);
            }
        }

        public void SetSenderAMSNetId(string amsNetId)
        {
            if (!string.IsNullOrEmpty(amsNetId))
            {
                StrToAMSNetId(amsNetId).CopyTo(sourceAMSNetId, 0);
                senderAMSNetId = amsNetId;
            }
        }

        public string GetSenderAMSNetId()
        {
            return GetAmsNetIdString(sourceAMSNetId, 0);
        }

        protected override OperateResult InitializationOnConnect(Socket socket)
        {
            if (string.IsNullOrEmpty(senderAMSNetId))
            {
                IPEndPoint iPEndPoint = (IPEndPoint)socket.LocalEndPoint;
                sourceAMSNetId[6] = BitConverter.GetBytes(iPEndPoint.Port)[0];
                sourceAMSNetId[7] = BitConverter.GetBytes(iPEndPoint.Port)[1];
                iPEndPoint.Address.GetAddressBytes().CopyTo(sourceAMSNetId, 0);
            }
            return base.InitializationOnConnect(socket);
        }

        //[AsyncStateMachine(typeof(<InitializationOnConnectAsync>d__16))]
        //[DebuggerStepThrough]
        //protected override Task<OperateResult> InitializationOnConnectAsync(Socket socket)
        //{
        //    <InitializationOnConnectAsync>d__16 stateMachine = new <InitializationOnConnectAsync>d__16();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.socket = socket;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public OperateResult<uint> ReadValueHandle(string address)
        {
            if (!address.StartsWith("s="))
            {
                return new OperateResult<uint>(StringResources.Language.SAMAddressStartWrong);
            }
            bool isBit = false;
            OperateResult<byte[]> operateResult = BuildReadWriteCommand(address, 4, isBit = false, StrToAdsBytes(address.Substring(2)));
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<uint>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<uint>(operateResult2);
            }
            OperateResult operateResult3 = CheckResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<uint>(operateResult3);
            }
            return OperateResult.CreateSuccessResult(BitConverter.ToUInt32(operateResult2.Content, 46));
        }

        public OperateResult<string> TransValueHandle(string address)
        {
            if (address.StartsWith("s="))
            {
                if (useTagCache)
                {
                    lock (tagLock)
                    {
                        if (tagCaches.ContainsKey(address))
                        {
                            return OperateResult.CreateSuccessResult(String.Format("i={0}", tagCaches[address]));
                        }
                    }
                }
                OperateResult<uint> operateResult = ReadValueHandle(address);
                if (!operateResult.IsSuccess)
                {
                    return OperateResult.CreateFailedResult<string>(operateResult);
                }
                if (useTagCache)
                {
                    lock (tagLock)
                    {
                        if (!tagCaches.ContainsKey(address))
                        {
                            tagCaches.Add(address, operateResult.Content);
                        }
                    }
                }
                return OperateResult.CreateSuccessResult(String.Format("i={0}", operateResult.Content));
            }
            return OperateResult.CreateSuccessResult(address);
        }

        [HslMqttApi("ReadAdsDeviceInfo", "读取Ads设备的设备信息。主要是版本号，设备名称")]
        public OperateResult<AdsDeviceInfo> ReadAdsDeviceInfo()
        {
            OperateResult<byte[]> operateResult = BuildReadDeviceInfoCommand();
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<AdsDeviceInfo>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<AdsDeviceInfo>(operateResult2);
            }
            OperateResult operateResult3 = CheckResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<AdsDeviceInfo>(operateResult3);
            }
            return OperateResult.CreateSuccessResult(new AdsDeviceInfo(operateResult2.Content.RemoveBegin(42)));
        }

        [HslMqttApi("ReadAdsState", "读取Ads设备的状态信息")]
        public OperateResult<ushort, ushort> ReadAdsState()
        {
            OperateResult<byte[]> operateResult = BuildReadStateCommand();
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<ushort, ushort>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<ushort, ushort>(operateResult2);
            }
            OperateResult operateResult3 = CheckResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<ushort, ushort>(operateResult3);
            }
            return OperateResult.CreateSuccessResult(BitConverter.ToUInt16(operateResult2.Content, 42), BitConverter.ToUInt16(operateResult2.Content, 44));
        }

        [HslMqttApi("WriteAdsState", "写入Ads的状态，可以携带数据信息，数据可以为空")]
        public OperateResult WriteAdsState(short state, short deviceState, byte[] data)
        {
            OperateResult<byte[]> operateResult = BuildWriteControlCommand(state, deviceState, data);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult operateResult3 = CheckResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            return OperateResult.CreateSuccessResult();
        }

        public OperateResult ReleaseSystemHandle(uint handle)
        {
            OperateResult<byte[]> operateResult = BuildReleaseSystemHandle(handle);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult operateResult3 = CheckResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            return OperateResult.CreateSuccessResult();
        }

        //[AsyncStateMachine(typeof(<ReadValueHandleAsync>d__23))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<uint>> ReadValueHandleAsync(string address)
        //{
        //    <ReadValueHandleAsync>d__23 stateMachine = new <ReadValueHandleAsync>d__23();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<uint>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<TransValueHandleAsync>d__24))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<string>> TransValueHandleAsync(string address)
        //{
        //    <TransValueHandleAsync>d__24 stateMachine = new <TransValueHandleAsync>d__24();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<string>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadAdsDeviceInfoAsync>d__25))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<AdsDeviceInfo>> ReadAdsDeviceInfoAsync()
        //{
        //    <ReadAdsDeviceInfoAsync>d__25 stateMachine = new <ReadAdsDeviceInfoAsync>d__25();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<AdsDeviceInfo>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadAdsStateAsync>d__26))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<ushort, ushort>> ReadAdsStateAsync()
        //{
        //    <ReadAdsStateAsync>d__26 stateMachine = new <ReadAdsStateAsync>d__26();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<ushort, ushort>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAdsStateAsync>d__27))]
        //[DebuggerStepThrough]
        //public Task<OperateResult> WriteAdsStateAsync(short state, short deviceState, byte[] data)
        //{
        //    <WriteAdsStateAsync>d__27 stateMachine = new <WriteAdsStateAsync>d__27();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.state = state;
        //    stateMachine.deviceState = deviceState;
        //    stateMachine.data = data;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReleaseSystemHandleAsync>d__28))]
        //[DebuggerStepThrough]
        //public Task<OperateResult> ReleaseSystemHandleAsync(uint handle)
        //{
        //    <ReleaseSystemHandleAsync>d__28 stateMachine = new <ReleaseSystemHandleAsync>d__28();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.handle = handle;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        [HslMqttApi("ReadByteArray", "")]
        public override OperateResult<byte[]> Read(string address, ushort length)
        {
            OperateResult<string> operateResult = TransValueHandle(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            address = operateResult.Content;
            OperateResult<byte[]> operateResult2 = BuildReadCommand(address, length, isBit: false);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            OperateResult operateResult4 = CheckResponse(operateResult3.Content);
            if (!operateResult4.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult4);
            }
            return OperateResult.CreateSuccessResult(SoftBasic.ArrayRemoveBegin(operateResult3.Content, 46));
        }

        [HslMqttApi("WriteByteArray", "")]
        public override OperateResult Write(string address, byte[] value)
        {
            OperateResult<string> operateResult = TransValueHandle(address);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            address = operateResult.Content;
            OperateResult<byte[]> operateResult2 = BuildWriteCommand(address, value, isBit: false);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            OperateResult operateResult4 = CheckResponse(operateResult3.Content);
            if (!operateResult4.IsSuccess)
            {
                return operateResult4;
            }
            return OperateResult.CreateSuccessResult();
        }

        [HslMqttApi("ReadBoolArray", "")]
        public override OperateResult<bool[]> ReadBool(string address, ushort length)
        {
            OperateResult<string> operateResult = TransValueHandle(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            address = operateResult.Content;
            OperateResult<byte[]> operateResult2 = BuildReadCommand(address, length, isBit: true);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult2);
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult3);
            }
            OperateResult operateResult4 = CheckResponse(operateResult3.Content);
            if (!operateResult4.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult4);
            }
            return OperateResult.CreateSuccessResult(SoftBasic.ByteToBoolArray(SoftBasic.ArrayRemoveBegin(operateResult3.Content, 46)));
        }

        [HslMqttApi("WriteBoolArray", "")]
        public override OperateResult Write(string address, bool[] value)
        {
            OperateResult<string> operateResult = TransValueHandle(address);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            address = operateResult.Content;
            OperateResult<byte[]> operateResult2 = BuildWriteCommand(address, value, isBit: true);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult<byte[]> operateResult3 = ReadFromCoreServer(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            OperateResult operateResult4 = CheckResponse(operateResult3.Content);
            if (!operateResult4.IsSuccess)
            {
                return operateResult4;
            }
            return OperateResult.CreateSuccessResult();
        }

        [HslMqttApi("ReadByte", "")]
        public OperateResult<byte> ReadByte(string address)
        {
            return ByteTransformHelper.GetResultFromArray(Read(address, 1));
        }

        [HslMqttApi("WriteByte", "")]
        public OperateResult Write(string address, byte value)
        {
            return Write(address, new byte[1]
		{
			value
		});
        }

        //[AsyncStateMachine(typeof(<ReadAsync>d__35))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
        //{
        //    <ReadAsync>d__35 stateMachine = new <ReadAsync>d__35();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__36))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, byte[] value)
        //{
        //    <WriteAsync>d__36 stateMachine = new <WriteAsync>d__36();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadBoolAsync>d__37))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult<bool[]>> ReadBoolAsync(string address, ushort length)
        //{
        //    <ReadBoolAsync>d__37 stateMachine = new <ReadBoolAsync>d__37();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__38))]
        //[DebuggerStepThrough]
        //public override Task<OperateResult> WriteAsync(string address, bool[] value)
        //{
        //    <WriteAsync>d__38 stateMachine = new <WriteAsync>d__38();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<ReadByteAsync>d__39))]
        //[DebuggerStepThrough]
        //public Task<OperateResult<byte>> ReadByteAsync(string address)
        //{
        //    <ReadByteAsync>d__39 stateMachine = new <ReadByteAsync>d__39();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte>>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__40))]
        //[DebuggerStepThrough]
        //public Task<OperateResult> WriteAsync(string address, byte value)
        //{
        //    <WriteAsync>d__40 stateMachine = new <WriteAsync>d__40();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.<>4__this = this;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public byte[] BuildAmsHeaderCommand(ushort commandId, byte[] data)
        {
            if (data == null)
            {
                data = new byte[0];
            }
            uint value = (uint)incrementCount.GetCurrentValue();
            byte[] array = new byte[32 + data.Length];
            targetAMSNetId.CopyTo(array, 0);
            sourceAMSNetId.CopyTo(array, 8);
            array[16] = BitConverter.GetBytes(commandId)[0];
            array[17] = BitConverter.GetBytes(commandId)[1];
            array[18] = 4;
            array[19] = 0;
            array[20] = BitConverter.GetBytes(data.Length)[0];
            array[21] = BitConverter.GetBytes(data.Length)[1];
            array[22] = BitConverter.GetBytes(data.Length)[2];
            array[23] = BitConverter.GetBytes(data.Length)[3];
            array[24] = 0;
            array[25] = 0;
            array[26] = 0;
            array[27] = 0;
            array[28] = BitConverter.GetBytes(value)[0];
            array[29] = BitConverter.GetBytes(value)[1];
            array[30] = BitConverter.GetBytes(value)[2];
            array[31] = BitConverter.GetBytes(value)[3];
            data.CopyTo(array, 32);
            return PackAmsTcpHelper(AmsTcpHeaderFlags.Command, array);
        }

        public OperateResult<byte[]> BuildReadDeviceInfoCommand()
        {
            return OperateResult.CreateSuccessResult(BuildAmsHeaderCommand(1, null));
        }

        public OperateResult<byte[]> BuildReadStateCommand()
        {
            return OperateResult.CreateSuccessResult(BuildAmsHeaderCommand(4, null));
        }

        public OperateResult<byte[]> BuildWriteControlCommand(short state, short deviceState, byte[] data)
        {
            if (data == null)
            {
                data = new byte[0];
            }
            byte[] array = new byte[8 + data.Length];
            return OperateResult.CreateSuccessResult(BuildAmsHeaderCommand(5, SoftBasic.SpliceArray<byte>(BitConverter.GetBytes(state), BitConverter.GetBytes(deviceState), BitConverter.GetBytes(data.Length), data)));
        }

        public OperateResult<byte[]> BuildReadCommand(string address, int length, bool isBit)
        {
            OperateResult<uint, uint> operateResult = AnalysisAddress(address, isBit);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            byte[] array = new byte[12];
            BitConverter.GetBytes(operateResult.Content1).CopyTo(array, 0);
            BitConverter.GetBytes(operateResult.Content2).CopyTo(array, 4);
            BitConverter.GetBytes(length).CopyTo(array, 8);
            return OperateResult.CreateSuccessResult(BuildAmsHeaderCommand(2, array));
        }

        public OperateResult<byte[]> BuildReadWriteCommand(string address, int length, bool isBit, byte[] value)
        {
            OperateResult<uint, uint> operateResult = AnalysisAddress(address, isBit);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            byte[] array = new byte[16 + value.Length];
            BitConverter.GetBytes(operateResult.Content1).CopyTo(array, 0);
            BitConverter.GetBytes(operateResult.Content2).CopyTo(array, 4);
            BitConverter.GetBytes(length).CopyTo(array, 8);
            BitConverter.GetBytes(value.Length).CopyTo(array, 12);
            value.CopyTo(array, 16);
            return OperateResult.CreateSuccessResult(BuildAmsHeaderCommand(9, array));
        }

        public OperateResult<byte[]> BuildWriteCommand(string address, byte[] value, bool isBit)
        {
            OperateResult<uint, uint> operateResult = AnalysisAddress(address, isBit);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            byte[] array = new byte[12 + value.Length];
            BitConverter.GetBytes(operateResult.Content1).CopyTo(array, 0);
            BitConverter.GetBytes(operateResult.Content2).CopyTo(array, 4);
            BitConverter.GetBytes(value.Length).CopyTo(array, 8);
            value.CopyTo(array, 12);
            return OperateResult.CreateSuccessResult(BuildAmsHeaderCommand(3, array));
        }

        public OperateResult<byte[]> BuildWriteCommand(string address, bool[] value, bool isBit)
        {
            OperateResult<uint, uint> operateResult = AnalysisAddress(address, isBit);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            byte[] array = SoftBasic.BoolArrayToByte(value);
            byte[] array2 = new byte[12 + array.Length];
            BitConverter.GetBytes(operateResult.Content1).CopyTo(array2, 0);
            BitConverter.GetBytes(operateResult.Content2).CopyTo(array2, 4);
            BitConverter.GetBytes(array.Length).CopyTo(array2, 8);
            array.CopyTo(array2, 12);
            return OperateResult.CreateSuccessResult(BuildAmsHeaderCommand(3, array2));
        }

        public OperateResult<byte[]> BuildReleaseSystemHandle(uint handle)
        {
            byte[] array = new byte[16];
            BitConverter.GetBytes(61446).CopyTo(array, 0);
            BitConverter.GetBytes(4).CopyTo(array, 8);
            BitConverter.GetBytes(handle).CopyTo(array, 12);
            return OperateResult.CreateSuccessResult(BuildAmsHeaderCommand(3, array));
        }

        public override string ToString()
        {
            return String.Format("BeckhoffAdsNet[{0}:{1}]", IpAddress, Port);
        }

        public static OperateResult CheckResponse(byte[] response)
        {
            try
            {
                int num = BitConverter.ToInt32(response, 30);
                if (num > 0)
                {
                    return new OperateResult(num, GetErrorCodeText(num) + Environment.NewLine + "Source:" + response.ToHexString(' '));
                }
                int num2 = BitConverter.ToInt32(response, 38);
                if (num2 != 0)
                {
                    return new OperateResult(num2, StringResources.Language.UnknownError + " Source:" + response.ToHexString(' '));
                }
            }
            catch (Exception ex)
            {
                return new OperateResult(ex.Message + " Source:" + response.ToHexString(' '));
            }
            return OperateResult.CreateSuccessResult();
        }

        public static byte[] PackAmsTcpHelper(AmsTcpHeaderFlags headerFlags, byte[] command)
        {
            byte[] array = new byte[6 + command.Length];
            BitConverter.GetBytes((ushort)headerFlags).CopyTo(array, 0);
            BitConverter.GetBytes(command.Length).CopyTo(array, 2);
            command.CopyTo(array, 6);
            return array;
        }

        public static OperateResult<uint, uint> AnalysisAddress(string address, bool isBit)
        {
            OperateResult<uint, uint> operateResult = new OperateResult<uint, uint>();
            try
            {
                if (address.StartsWith("i="))
                {
                    operateResult.Content1 = 61445u;
                    operateResult.Content2 = uint.Parse(address.Substring(2));
                }
                else if (address.StartsWith("s="))
                {
                    operateResult.Content1 = 61443u;
                    operateResult.Content2 = 0u;
                }
                else
                {
                    switch (address[0])
                    {
                        case 'M':
                        case 'm':
                            if (isBit)
                            {
                                operateResult.Content1 = 16417u;
                            }
                            else
                            {
                                operateResult.Content1 = 16416u;
                            }
                            break;
                        case 'I':
                        case 'i':
                            if (isBit)
                            {
                                operateResult.Content1 = 61473u;
                            }
                            else
                            {
                                operateResult.Content1 = 61472u;
                            }
                            break;
                        case 'Q':
                        case 'q':
                            if (isBit)
                            {
                                operateResult.Content1 = 61489u;
                            }
                            else
                            {
                                operateResult.Content1 = 61488u;
                            }
                            break;
                        default:
                            throw new Exception(StringResources.Language.NotSupportedDataType);
                    }
                    operateResult.Content2 = uint.Parse(address.Substring(1));
                }
            }
            catch (Exception ex)
            {
                operateResult.Message = ex.Message;
                return operateResult;
            }
            operateResult.IsSuccess = true;
            operateResult.Message = StringResources.Language.SuccessText;
            return operateResult;
        }

        public static byte[] StrToAdsBytes(string value)
        {
            return SoftBasic.SpliceArray<byte>(Encoding.ASCII.GetBytes(value), new byte[1]);
        }

        public static byte[] StrToAMSNetId(string amsNetId)
        {
            string text = amsNetId;
            byte[] array;
            if (amsNetId.IndexOf(':') > 0)
            {
                array = new byte[8];
                string[] array2 = amsNetId.Split(new char[1]
			{
				':'
			}, StringSplitOptions.RemoveEmptyEntries);
                text = array2[0];
                array[6] = BitConverter.GetBytes(int.Parse(array2[1]))[0];
                array[7] = BitConverter.GetBytes(int.Parse(array2[1]))[1];
            }
            else
            {
                array = new byte[6];
            }
            string[] array3 = text.Split(new char[1]
		{
			'.'
		}, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < array3.Length; i++)
            {
                array[i] = byte.Parse(array3[i]);
            }
            return array;
        }

        public static string GetAmsNetIdString(byte[] data, int index)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(data[index]);
            stringBuilder.Append(".");
            stringBuilder.Append(data[index + 1]);
            stringBuilder.Append(".");
            stringBuilder.Append(data[index + 2]);
            stringBuilder.Append(".");
            stringBuilder.Append(data[index + 3]);
            stringBuilder.Append(".");
            stringBuilder.Append(data[index + 4]);
            stringBuilder.Append(".");
            stringBuilder.Append(data[index + 5]);
            stringBuilder.Append(":");
            stringBuilder.Append(BitConverter.ToUInt16(data, index + 6));
            return stringBuilder.ToString();
        }

        public static string GetErrorCodeText(int error)
        {
            switch (error)
            {
                case 0:
                    return "NO ERROR";
                case 1:
                    return "INTERNAL";
                case 2:
                    return "NO RTIME";
                case 3:
                    return "ALLOC LOCKED MEM";
                case 4:
                    return "INSERT MAILBOX";
                case 5:
                    return "WRONGRECEIVEHMSG";
                case 6:
                    return "TARGET PORT NOT FOUND";
                case 7:
                    return "TARGET MACHINE NOT FOUND";
                case 8:
                    return "UNKNOWN CMDID";
                case 9:
                    return "BAD TASKID";
                case 10:
                    return "NOIO";
                case 11:
                    return "UNKNOWN AMSCMD";
                case 12:
                    return "WIN32 ERROR";
                case 13:
                    return "PORT NOT CONNECTED";
                case 14:
                    return "INVALID AMS LENGTH";
                case 15:
                    return "INVALID AMS NETID";
                case 16:
                    return "LOW INST LEVEL";
                case 17:
                    return "NO DEBUG INT AVAILABLE";
                case 18:
                    return "PORT DISABLED";
                case 19:
                    return "PORT ALREADY CONNECTED";
                case 20:
                    return "AMSSYNC_W32ERROR";
                case 21:
                    return "AMSSYNC_TIMEOUT";
                case 22:
                    return "AMSSYNC_AMSERROR";
                case 23:
                    return "AMSSYNC_NOINDEXINMAP";
                case 24:
                    return "INVALID AMSPORT";
                case 25:
                    return "NO MEMORY";
                case 26:
                    return "TCP SEND";
                case 27:
                    return "HOST UNREACHABLE";
                default:
                    return StringResources.Language.UnknownError;
            }
        }
    }
}
